"""File written by Christian Kleineidam"""
import re

def readDictionary():
    print("readDictionary")
    proteinDictionaryFile = open("spezies_geneID_Liste.txt", 'r')

    proteinMapping = {}

    for line in proteinDictionaryFile:
        words = line.split(" ")
        proteinMapping[words[0][1:]] = words[1][1:]
        #clean the "> at the beginning of the file

    return proteinMapping

"""For every protein in the referenz
genome builds a group with includes all linked proteins"""


class ProteinMatch:
    def __init__(self, name, score):
        self.name = name
        self.score = score
        
    def __str__(self):
        return self.name

    def getScore(self):
        return self.score

class ProteinConserv:
    def __init__(self, originalProtein):
        self.name = originalProtein
        self.specMatches = {}
        self.numberOverCutOff = 0
        self.totalNumber = 0
        
    def addMatch(self, otherProteinName, score, cutoff, proteinMapping):
        if (score > cutoff and str(self) != otherProteinName and
            otherProteinName in proteinMapping):
            
            species = proteinMapping[otherProteinName]
            if not species in self.specMatches:
                self.specMatches[species] = []
            
            match = ProteinMatch(otherProteinName, score)
            self.specMatches[species].append(match)
            self.totalNumber += 1
    def hasInparaloge(self):
        if str(self) in self.specMatches:
            return True
        else:
            return False
    

    def countSpecies(self):
        """Return the number of species in which there's at least one"""
        if str(self) in self.specMatches:
            return len(self.specMatches) - 1
        else:
            return len(self.specMatches)
    
    def getParalogCount(self):
        """Gets the Score of the HighestMatch with """
        pass

    def __str__(self):
        return self.name

def convertNumber(stringNumber):
    return int(stringNumber.split(".")[0])


def buildConservations(cutoff, proteinMapping):
    print("buildConservations")
    resultsFile = open("whole_erg.txt", "r")

    originalProtein = ""
    conservations = []
    singleConservation = None 
    linenumber = 0
    for line in resultsFile:
        linenumber +=1
        if linenumber%100000 == 0:
            print("Line: " + str(linenumber))
        
        if line[0] != "#":        
            space = re.compile(r'\s')
            words = space.split(line)
            firstProtein = words[0]
            secondProtein = words[1]
            score = convertNumber(words[2])

            if firstProtein != originalProtein:
                originalProtein = firstProtein
                singleConservation = ProteinConserv(originalProtein)
                conservations.append(singleConservation)
            singleConservation.addMatch(secondProtein, score, cutoff, proteinMapping)
    
    return conservations


def getData(proteinMapping, conservations, inparaloge):
    for minimumSpeziesMatchs in range (1, 22):
        number = 0
        for conv in conservations:
            if (conv.countSpecies() > minimumSpeziesMatchs and
                (inparaloge or conv.hasInparaloge())):
                number += 1
        print(str(minimumSpeziesMatchs) + " " + str(number))

def getNames(proteinMapping, conservations, inparaloge):
    for conv in conservations:
        if (conv.countSpecies() > 19
            and proteinMapping[str(conv)]=="Bacteroides" and
            (inparaloge or conv.hasInparaloge())):
            
            print("\nMain Protein for: "  + str(conv))
            for speciesMatches in conv.specMatches.values():                
                prot = str(speciesMatches[0])
                print(proteinMapping[prot] + ": " + prot)

def myScript():
    cutoff = 50
    inparaloge = False
    proteinMapping = readDictionary()
    
    conservations = buildConservations(cutoff, proteinMapping)
    getData(proteinMapping, conservations, inparaloge)
    getNames(proteinMapping, conservations, inparaloge)

def getCutoffListe():
    pass


